package com.fbb.codegen.core;

import java.sql.Connection;
import java.util.Date;

import org.apache.commons.lang3.time.DateFormatUtils;


/**
 * 代码生成器
 * 
 * @author fanbeibei
 *
 */
public abstract class CodeGen {

	/**
	 * 包声明
	 */
	public static final String PACKAGE_DECLARATION = "package {{packageName}};\n\n";

	/**
	 * 导包声明
	 */
	public static final String IMPORT_DECLARATION = "import {{className}};\n";

	/**
	 * 必须有的import语句
	 */
	public static final String MUST_IMPORT = 
			"\r\nimport javax.persistence.Column;\n"
			+ "import javax.persistence.Entity;\n" 
			+ "import javax.persistence.Id;\n"
			+ "import javax.persistence.SequenceGenerator;\n" 
			+ "import javax.persistence.Table;\n"
			+ "import javax.persistence.UniqueConstraint;\n\n"
			+ "import org.apache.commons.lang3.builder.ToStringBuilder;\n"
			+ "import org.apache.commons.lang3.builder.ToStringStyle;\n\n" 
			+ "import lombok.Data;\n\t\n";

	/**
	 * 类声明
	 */
	public static final String CLASS_DECLARATION = 
			"/**\n" 
			+ " *\n" 
			+ " * <p>\n"
			+ " * {{classComment}}\n"
			+ " * </p>\n"
			+ " * @author {{author}}\n"
			+ " * @since {{now}}\n" 
			+ " */\n" 
			+ "@Data \n" 
			+ "@Entity \n"
			+ "@Table(name = \"{{tableName}}\", uniqueConstraints = { @UniqueConstraint(columnNames = { \"{{idName}}\" }) })\n"
			+ "public class {{className}} {\n\n";

	/**
	 * id变量声明
	 */
	public static final String ID_VAR_DECLARATION = 
			"\t/**\n\t" 
			+ " *{{idComment}}\n\t" 
			+ " */\n\t" 
			+ "@Id\n\t"
			+ "@SequenceGenerator(name = \"{{tableName}}\")\n\t"
			+ "@Column(name = \"{{idName}}\")\n\tprivate {{type}} {{idPropName}};\n\t\n\t";

	/**
	 * 普通变量声明
	 */
	public static final String VAR_DECLARATION = 
			"/**\n\t" 
			+ " *{{varComment}}\n\t" 
			+ " */\n\t"
			+ "@Column(name = \"{{columName}}\")\n\tprivate {{type}} {{varName}};\n\t\n\t";

	/**
	 * toString 方法
	 */
	public static final String TO_STRING = 
			"@Override\r\n" 
			+ "	public String toString() {\r\n"
			+ "		return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);\r\n" 
			+ "	}\r\n";

	public static final String END = "\n}";

	/**
	 * 创建包声明
	 * 
	 * @param packageName 包名
	 * @return
	 */
	public String createPackageDeclaration(final String packageName) {
		return PACKAGE_DECLARATION.replaceAll("\\{\\{packageName\\}\\}", packageName);
	}

	public String createImportDeclaration(final String className) {
		return IMPORT_DECLARATION.replaceAll("\\{\\{className\\}\\}", className);
	}

	/**
	 * 
	 * 创建类声明
	 * 
	 * @param tableName 表名
	 * @param idName    id 列名
	 * @param className 类名
	 * @return
	 */
	public String createClassDeclaration(final String tableName, final String idName, final String className,final String author,final String classComment) {
		return CLASS_DECLARATION.replaceAll("\\{\\{tableName\\}\\}", tableName).replaceAll("\\{\\{idName\\}\\}", idName)
				.replaceAll("\\{\\{className\\}\\}", className)
				.replaceAll("\\{\\{author\\}\\}", author)
				.replaceAll("\\{\\{now\\}\\}", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
				.replaceAll("\\{\\{classComment\\}\\}", classComment);
	}

	/**
	 * 创建id变量声明
	 * 
	 * @param idComment    注释
	 * @param tableName  表名
	 * @param idName     id列名
	 * @param type       id类型
	 * @param idPropName id属性名
	 * @return
	 */
	public String createIdVarDeclaration(final String idComment, final String tableName, final String idName,
			final String type, String idPropName) {
		return ID_VAR_DECLARATION.replaceAll("\\{\\{idComment\\}\\}", idComment)
				.replaceAll("\\{\\{tableName\\}\\}", tableName).replaceAll("\\{\\{idName\\}\\}", idName)
				.replaceAll("\\{\\{type\\}\\}", type).replaceAll("\\{\\{idPropName\\}\\}", idPropName);

	}

	/**
	 * 创建普通变量声明
	 * 
	 * @param varComment   注释
	 * @param columName 列名
	 * @param type      类型
	 * @param varName   变量名
	 * @return
	 */
	public String createVarDeclaration(final String varComment, final String columName, final String type,
			final String varName) {

		return VAR_DECLARATION.replaceAll("\\{\\{varComment\\}\\}", varComment).replaceAll("\\{\\{columName\\}\\}", columName)
				.replaceAll("\\{\\{type\\}\\}", type).replaceAll("\\{\\{varName\\}\\}", varName);
	}

	/**
	 * 创建所有的实体文件
	 * 
	 * @param fileOutPath 输出文件路径
	 * @param packageName 包名
	 * @param author  作者
	 */
	public abstract void createAllTableEntityFile(final String fileOutPath, final String packageName,final String author,final String tableNamePrefix);

	/**
	 * 设置 数据库连接
	 * 
	 * @param conn 数据库连接
	 */
	public abstract void setConn(final Connection conn);
}
